<template>
  <div class="table-container">
    <search-bar v-model="queryParams" :config="searchColumn" @search="handleSearch" @searchReset="handleReset" key="users" />
    <table-page
      width="100%"
      class="user-table"
      :tableData="tableData"
      :tableColumn="tableColumn"
      :isIndex="true"
      :isSelection="false"
      :total="pages.total"
      :pageSize="pages.pageSize"
      :currentPage="pages.pageNum"
      @sizeChange="handleSizeChange"
      @currentChange="handleCurrentChange"
    >
      <template #handle>
        <el-button class="m_96" type="primary" v-hasPermi="['CentralControl.IdentityUser.Create']" icon="el-icon-plus" @click="handleUserDialog">
          人员
        </el-button>
      </template>
    </table-page>

    <!-- 新增/编辑人员 -->
    <el-dialog
      width="470px"
      class="app-dialog"
      :title="`${userDialogType}人员`"
      :visible.sync="userDialogVisible"
      :before-close="handleUserDialogClose"
      :close-on-click-modal="false"
    >
      <div class="container">
        <Form ref="userEdit" v-model="userDialogData" :config="userDialogConfig" label-width="80px" label-position="top" />
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="handleUserDialogClose">取 消</el-button>
        <el-button type="primary" @click="handleUserSubmit">确 定</el-button>
      </span>
    </el-dialog>

    <!-- 权限弹窗 -->
    <el-dialog
      width="40%"
      class="app-dialog"
      title="编辑权限"
      :visible.sync="authDialogVisible"
      :before-close="handleAuthDialogClose"
      :close-on-click-modal="false"
    >
      <div class="container" style="height: 450px; overflow-y: scroll" v-if="authDialogVisible">
        <el-tree
          ref="authTree"
          show-checkbox
          :data="authOptions"
          node-key="name"
          :props="{
            value: 'name',
            label: 'displayName',
            children: 'children',
          }"
          :default-expand-all="true"
          :default-checked-keys="checkedKeys"
          :check-strictly="false"
        />
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="handleAuthDialogClose">取 消</el-button>
        <el-button type="primary" @click="handleAuthSubmit">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import Form from '@/components/Form'
import SearchBar from '@/components/SearchBar'
import TablePage from '@/components/TablePage'
import { validPhone, validEmail } from '@/utils/validate'
import {
  addUser,
  putUser,
  delUser,
  orgUser,
  roleUser,
  exitsPhone,
  getUserList,
  getJobsList,
  getDepartmentsList,
  getUserOrgCode,
  getUserPermissions,
  putUserPermissions,
} from '@/api/identity'

export default {
  name: 'UserSearchTable',
  components: {
    SearchBar,
    TablePage,
    Form,
  },
  data: function () {
    return {
      timer: '',
      queryParams: {},
      searchColumn: [
        {
          prop: 'UserName',
          type: 'input',
          placeholder: '账号名称',
        },
        {
          prop: 'phoneNumber',
          type: 'input',
          placeholder: '手机号',
        },
        {
          prop: 'name',
          type: 'input',
          placeholder: '姓名',
        },
        {
          prop: 'jobId',
          type: 'select',
          placeholder: '岗位',
        },
        {
          prop: 'departmentId',
          type: 'select',
          placeholder: '部门',
        },
        {
          prop: 'roleId',
          type: 'select',
          placeholder: '角色',
        },
      ],
      tableData: [],
      tableColumn: [
        {
          label: '账号',
          prop: 'userName',
        },
        {
          label: '姓名',
          prop: 'name',
        },
        {
          label: '岗位',
          prop: 'jobName',
        },
        {
          label: '部门',
          prop: 'departmentName',
        },
        {
          label: '角色',
          prop: 'roleNames',
        },
        {
          label: '手机号',
          prop: 'phoneNumber',
        },
        {
          label: '邮箱',
          prop: 'email',
        },
        // {
        //   label: '是否启用',
        //   prop: 'isActive',
        //   type: 'switch',
        //   width: '120px',
        // },
        {
          label: '操作',
          prop: 'action',
          fixed: 'right',
          type: 'button',
          width: 150,
          buttons: [
            {
              label: '编辑',
              type: 'text',
              color: 'rgba(0, 118, 255, 1)',
              method: 'handleEdit',
              policy: ['CentralControl.IdentityUser.Update'],
            },
            {
              label: '权限',
              type: 'text',
              color: 'rgba(0, 118, 255, 1)',
              method: 'handleAuth',
              policy: ['CentralControl.IdentityUser.Permission'],
            },
            {
              label: '删除',
              type: 'text',
              color: '#F37272',
              method: 'handleDelete',
              policy: ['CentralControl.IdentityUser.Delete'],
            },
          ],
        },
      ],
      // 人员编辑弹窗配置
      userDialogType: '',
      userDialogVisible: false,
      userDialogData: {},
      userDialogConfig: [
        {
          label: '账号',
          prop: 'userName',
          type: 'input',
          disabled: false,
          placeholder: '请输入人员账号',
          rules: [{ required: true, trigger: 'change', message: '请输入人员账号' }],
        },
        {
          label: '姓名',
          prop: 'name',
          type: 'input',
          disabled: false,
          placeholder: '请输入人员姓名',
          rules: [{ required: true, trigger: 'change', message: '请输入人员姓名' }],
        },
        {
          label: '密码',
          prop: 'password',
          type: 'input-password',
          password: true,
          placeholder: '初始默认123456;限6~20个英文、数字,区分大小写',
          rules: [],
        },
        {
          label: '邮箱',
          prop: 'email',
          type: 'input',
          placeholder: '请输入邮箱',
          rules: [
            { required: true, trigger: 'change', message: '请输入邮箱' },
            { required: true, validator: this.validEmail, trigger: 'change' },
          ],
        },
        {
          label: '手机号',
          prop: 'phoneNumber',
          type: 'input',
          placeholder: '请输入手机号',
          rules: [
            { required: true, trigger: 'blur', message: '请输入手机号' },
            { required: true, validator: this.validPhone, trigger: 'change' },
            {
              required: true,
              validator: this.exitsPhoneValid,
              trigger: 'blur',
            },
          ],
        },
        {
          label: '所属系统组织',
          prop: 'orgIds',
          type: 'cascader',
          multiple: true,
          emitPath: false,
          checkStrictly: true,
          props: {
            value: 'id',
            label: 'displayName',
            children: 'children',
          },
          options: [],
          async: this.getOrgDict,
          rules: [{ required: true, trigger: 'blur', message: '请选择所属系统组织' }],
        },
        {
          label: '角色',
          prop: 'roleNames',
          type: 'cascader',
          multiple: true,
          emitPath: false,
          options: [],
          async: this.getRoleDict,
          rules: [{ required: false, trigger: 'blur', message: '请选择角色' }],
        },
      ],
      // 权限编辑弹窗
      authDialogVisible: false,
      authOptions: [],
      providerKey: '',
      checkedKeys: [],
      changeNodes: [],
      roleDicts: [],
      pages: {
        total: 0,
        pageNum: 1,
        pageSize: 10,
      },
    }
  },
  props: {
    uid: {
      type: String,
      required: true,
    },
    org: {
      type: String,
      require: true,
    },
  },
  watch: {
    uid: {
      handler: function (nval) {
        if (nval) this.init()
      },
      immediate: true,
    },
    ['userDialogData.userName']: {
      handler: function (nval) {
        if (!nval || this.userDialogData.id) return
        if (this.timer) clearTimeout(this.timer)
        this.timer = setTimeout(() => {
          getUserOrgCode({ userName: nval }).then(async id => {
            if (id) {
              this.$set(
                this.userDialogConfig.find(item => {
                  return item.prop == 'orgIds'
                }),
                'options',
                await this.getOrgDict(true, this.org)
              )
              this.$set(this.userDialogData, 'orgIds', [id])
            }
          })
        }, 500)
      },
    },
  },
  async mounted() {
    // 编辑人员
    this.$bus.$on('handleEdit', async rows => {
      const orgsRoles = await this.getUserRoleOrg(rows.id)
      this.userDialogType = '编辑'
      this.userDialogVisible = true
      this.userDialogData = Object.assign({}, rows, orgsRoles)
      this.setPsdUsername()
    })

    // 权限
    this.$bus.$on('handleAuth', rows => {
      this.providerKey = rows.id
      getUserPermissions({ providerKey: rows.id, providerName: 'U' }).then(res => {
        this.convertTree(res)
        this.authDialogVisible = true
      })
    })

    // 删除人员
    this.$bus.$on('handleDelete', rows => {
      this.$confirm(`确认删除账号为" ${rows.userName} "的用户吗？`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }).then(() => {
        delUser(rows.id).then(res => {
          if (this.pages.total % this.pages.pageSize === 1) {
            const lastpage = (this.pages.total + this.pages.pageSize - 1) / this.pages.pageSize
            if (this.pages.pageNum == lastpage) {
              this.pages.pageNum = this.pages.pageNum - 1
            }
          }
          this.getTableData()
          this.$message({ type: 'success', message: '删除人员成功!' })
        })
      })
    })
  },
  destroyed() {
    this.$bus.$off('handleEdit')
    this.$bus.$off('handleAuth')
    this.$bus.$off('handleDelete')
  },

  methods: {
    async init() {
      await this.getRoleDict()
      this.initDicts()
      this.getTableData()
    },
    async initDicts() {
      const jobs = await this.getJobDict()
      const departments = await this.getDepartmentDict()
      this.$set(
        this.searchColumn.find(i => i.prop == 'roleId'),
        'options',
        this.roleDicts
      )
      this.$set(
        this.searchColumn.find(i => i.prop == 'jobId'),
        'options',
        jobs
      )
      this.$set(
        this.searchColumn.find(i => i.prop == 'departmentId'),
        'options',
        departments
      )
    },
    getTableData() {
      const params = {
        ouId: this.uid,
        SkipCount: (this.pages.pageNum - 1) * this.pages.pageSize,
        MaxResultCount: this.pages.pageSize,
        ...this.queryParams,
      }
      getUserList(params).then(res => {
        this.tableData = res.items
        this.pages.total = res.totalCount
      })
    },
    async handleUserSubmit() {
      const flag = await this.$refs.userEdit.validate()
      if (!flag) return
      this.userSubmitFunc({
        isAdd: true,
        isActive: true,
        OAStaffCode: null,
        ...this.userDialogData,
      })
    },
    async userSubmitFunc(data) {
      const id = this.userDialogData.id
      id ? await putUser(data) : await addUser(data)
      this.getTableData()
      this.handleUserDialogClose()
      this.$message.success(`人员${this.userDialogType}成功`)
      this.$emit('success')
    },
    // 获取人员组织角色信息
    async getUserRoleOrg(id) {
      return Promise.all([orgUser(id), roleUser(id)]).then(res => {
        const orgIds = res[0]['items'].map(i => i.id)
        const roleNames = res[1]['items'].map(i => i.name)
        return { orgIds, roleNames }
      })
    },
    handleAuthSubmit() {
      this.changeNodes = []
      let checkedKeys = this.$refs.authTree.getCheckedKeys()
      checkedKeys.forEach(item => {
        if (this.checkedKeys.indexOf(item) == -1) {
          this.changeNodes.push({ isGranted: true, name: item })
        }
      })
      this.checkedKeys.forEach(item => {
        if (checkedKeys.indexOf(item) == -1) {
          this.changeNodes.push({ isGranted: false, name: item })
        }
      })
      putUserPermissions(this.providerKey, 'U', {
        permissions: this.changeNodes,
      }).then(res => {
        this.$message.success('操作成功')
        this.handleAuthDialogClose()
      })
    },
    handleSearch() {
      this.pages.pageNum = 1
      this.getTableData()
    },
    handleReset() {
      this.pages.pageNum = 1
      this.getTableData()
    },
    handleSizeChange(v) {
      this.pages.pageSize = v
      this.pages.pageNum = 1
      this.getTableData()
    },
    handleCurrentChange(v) {
      this.pages.pageNum = v
      this.getTableData()
    },
    async handleUserDialog() {
      this.userDialogType = '新增'
      this.userDialogVisible = true
      this.setPsdUsername()
    },
    handleUserDialogClose() {
      this.userDialogData = {}
      this.$refs.userEdit.resetFields()
      this.userDialogVisible = false
    },
    handleAuthDialogClose() {
      this.authDialogVisible = false
    },
    validEmail(rule, value, callback) {
      validEmail(value) ? callback() : callback(new Error('请输入正确的邮箱'))
    },
    validPhone(rule, value, callback) {
      validPhone(value) ? callback() : callback(new Error('请输入正确的手机号'))
    },
    async exitsPhoneValid(rule, value, callback) {
      if (!value) return
      const notUserName = this.userDialogData.id ? this.userDialogData.userName : ''
      const valid = await exitsPhone({ phone: value, notUserName })
      valid ? callback(new Error('手机号存在')) : callback()
    },
    passwordValid(rule, value, callback) {
      const reg = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[!@#$%^&*()_+~`|}{[\]:;?><,./-])[A-Za-z\d!@#$%^&*()_+~`|}{[\]:;?><,./-]{6,20}$/
      reg.test(value) ? callback() : callback(new Error('密码长度不少于6个字符不超过20个字符，必须包含数字、字母、符号'))
    },
    async getJobDict() {
      const { data } = await getJobsList({ skipCount: 0, maxResultCount: 1000 })
      return data.map(item => {
        return { label: item.value, value: item.key }
      })
    },
    async getDepartmentDict() {
      const { data } = await getDepartmentsList({ skipCount: 0, maxResultCount: 1000 })
      return data.map(item => {
        return { label: item.value, value: item.key }
      })
    },
    async getRoleDict() {
      let roleDicts = await this.$store.dispatch('dicts/getRoleList', {
        params: { ouId: this.uid, skipCount: 0, maxResultCount: 1000 },
        refresh: true,
      })
      let result = roleDicts.map(item => {
        return { label: item.name, value: `CentralControl_${item.name}` }
      })
      this.roleDicts = roleDicts.map(item => {
        return { label: item.name, value: item.id }
      })
      return result
    },
    async getOrgDict(refresh, org) {
      let orgDicts = await this.$store.dispatch('dicts/getOrgList', { params: { id: org || this.uid }, refresh })
      return this.formatData(orgDicts)
    },
    setPsdUsername() {
      const rule = [
        { required: true, trigger: 'change', message: '请输入密码' },
        { required: true, validator: this.passwordValid, trigger: 'change' },
      ]
      const $id = this.userDialogData.id
      const psd = this.userDialogConfig.find(i => i.prop == 'password')
      const uName = this.userDialogConfig.find(i => i.prop == 'userName')
      this.$set(uName, 'disabled', !$id ? false : true)
      this.$set(psd, 'rules', !$id ? rule : [])
    },

    convertTree(data) {
      const _this = this
      let treeList = []
      let checkedArray = []
      function setChild(arr, item) {
        let parentList = arr.filter(a => a.parentName == item.name)
        if (item.isGranted) {
          checkedArray.push(item.name)
        }

        if (parentList && parentList.length > 0) {
          item.children = parentList
          item.children.map(child => {
            setChild(arr, child)
          })
        }
        _this.$set(item, 'disabled', item.grantedProviders[0]?.providerName == 'R')
        return item
      }
      if (data.groups) {
        const list1 = data.groups.find(f => f.name == 'Crm')
        const list2 = data.groups.find(f => f.name == 'CentralControl')
        if (list1 && list2) {
          let permissions = list1.permissions.concat(list2.permissions)
          let parentList = permissions.filter(item => item.parentName == null)
          parentList.forEach(a => {
            let item = setChild(permissions, a)
            treeList.push(item)
          })
        }
      }
      this.authOptions = treeList
      this.checkedKeys = checkedArray
    },
    formatData(data) {
      for (var i = 0; i < data.length; i++) {
        if (!data[i].children || data[i].children.length == 0) {
          data[i].children = undefined
        } else {
          this.formatData(data[i].children)
        }
      }
      return data
    },
  },
}
</script>

<style lang="scss" scoped>
::v-deep .el-dialog__body .container {
  padding: 20px 0;
  .el-form-item {
    padding: 0;
  }
}
</style>
